const io = require("socket.io");

module.exports = (app) => {
  const server = io(app);
  const client2socket = {};
  const socket2client = {};
  let currentGame = null;

  server.on("connection", (socket) => {
    console.log("new-connection: ", socket.id);
    console.log("client2socket", client2socket);
    console.log("socket2client", socket2client);

    // 【事件】检查昵称是否已经被占用
    // ---------------------------------------------------
    socket.on("check_user_exist", (nickname, callback) => {
      callback(!!client2socket[nickname]);
    });

    // 【事件】用户进入游戏
    // ---------------------------------------------------
    socket.on("enter", (nickname) => {
      const sid = socket.id;

      // 添加用户信息
      client2socket[nickname] = sid;
      socket2client[sid] = nickname;

      // 发送用户列表给当前用户
      socket.emit("room_info", {
        nicknames: Object.keys(client2socket),
        holder: currentGame?.holder,
        lines: currentGame?.lines || [],
      });

      // 发送新进用户给其他用户
      socket.broadcast.emit("user_enter", nickname);
    });

    // 【事件】用户离开游戏
    // ---------------------------------------------------
    socket.on("leave", () => {
      const sid = socket.id;
      const nickname = socket2client[sid];

      // 移除用户信息
      delete client2socket[nickname];
      delete socket2client[sid];

      // 如果当前离开的是游戏主持人
      if (currentGame && currentGame.holder === nickname) {
        currentGame = null;
      }

      // 发送离开用户给其他用户
      socket.broadcast.emit("user_leave", nickname);
    });

    // 【事件】申请开始游戏
    // ---------------------------------------------------
    socket.on("start_game", (finalAnswer) => {
      const sid = socket.id;
      const finalAnswerCount = finalAnswer.length;

      if (currentGame) {
        // 当前游戏已经处于开始状态
        socket.emit("already_started", currentGame.holder, finalAnswerCount);
        return;
      }

      // 设置当前游戏信息
      currentGame = {
        success: false,
        holder: socket2client[sid],
        finalAnswer,
        lines: [],
      };

      server.of("/").emit("game_started", currentGame.holder, finalAnswerCount);
    });

    // 【事件】申请终止游戏
    // ---------------------------------------------------
    socket.on("stop_game", () => {
      const sid = socket.id;
      const nickname = socket2client[sid];

      if (currentGame && nickname === currentGame.holder) {
        currentGame = null;
        server.of("/").emit("game_stopped");
      }
    });

    // 【事件】主持人发送提示
    // ---------------------------------------------------
    socket.on("give_advice", (advice) => {
      const sid = socket.id;
      const nickname = socket2client[sid];

      if (currentGame && nickname === currentGame.holder) {
        server.of("/").emit("receive_advice", advice);
      }
    });

    // 【事件】用户回答答案
    // ---------------------------------------------------
    socket.on("answer_game", (answer) => {
      const sid = socket.id;
      if (!currentGame) return;

      if (currentGame.success) {
        socket.emit("game_answered", { alreadyDone: true });
      } else {
        const success = currentGame.finalAnswer === answer;

        if (success) {
          currentGame.success = true;
        }

        server.of("/").emit("game_answered", {
          alreadyDone: false,
          success,
          nickname: socket2client[sid],
          answer,
        });
      }
    });

    // 【事件】重置游戏
    // ---------------------------------------------------
    socket.on("reset_game", () => {
      if (!currentGame) return;

      current = null;
      server.of("/").emit("game_reset", { gameReset: true });
    });

    // 【事件】用户绘图
    // ---------------------------------------------------
    socket.on("new_line", (line) => {
      if (currentGame?.lines) {
        currentGame.lines.push(line);
        socket.broadcast.emit("starting_line", line);
      }
    });

    socket.on("update_line", (line) => {
      if (currentGame?.lines) {
        currentGame.lines[currentGame.lines.length - 1] = line;
        socket.broadcast.emit("updating_line", line);
      }
    });

    socket.on("clear_line", () => {
      if (currentGame?.lines) {
        currentGame.lines = [];
        socket.broadcast.emit("lines_is_clear", []);
      }
    });

    // 【事件】客户端断开连接
    // ---------------------------------------------------
    socket.on("disconnect", () => {
      const sid = socket.id;
      const nickname = socket2client[sid];

      delete client2socket[nickname];
      delete socket2client[sid];

      // 如果当前离开的是游戏主持人
      if (currentGame && nickname === currentGame.holder) {
        currentGame = null;
      }

      // 发送离开的用户信息给其他用户
      socket.broadcast.emit("user_leave", nickname);
    });
  });
};
